package com.trade.okxserver.util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Date;

public class OKAccessSignGenerator {

    public static String generateOKAccessSign(String timestamp, String method, String requestPath, String body, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
        String message = timestamp + method + requestPath + (body != null ? body : "");
        byte[] hmacSha256Bytes = hmacSha256(message, secretKey);
        return Base64.getEncoder().encodeToString(hmacSha256Bytes);
    }

    private static byte[] hmacSha256(String message, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        hmacSha256.init(secretKeySpec);
        return hmacSha256.doFinal(message.getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
        String timestamp = getISO8601Timestamp();
        String method = "GET";
        String requestPath = "/api/v5/account/balance";
        String body = "{\"instId\":\"BTC-USDT\",\"lever\":\"5\",\"mgnMode\":\"isolated\"}";
        String secretKey = "yourSecretKeyHere";

        String sign = generateOKAccessSign(timestamp, method, requestPath, body, secretKey);
        System.out.println("OK-ACCESS-SIGN: " + sign);
    }

    public static String getISO8601Timestamp() {
        OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
        return getISO8601Timestamp(now);
    }

    public static String getISO8601Timestamp(OffsetDateTime offsetDateTime) {
        String timestamp = offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        return timestamp.substring(0, timestamp.length() - 6) + timestamp.substring(timestamp.length() - 2);
    }

    public static String getISO8601Timestamp(Date date) {
        Instant instant = date.toInstant();
        return instant.atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    }
}

